#ifndef MARKERPATH_H
#define MARKERPATH_H

#include <QObject>
#include <QLineF>
#include "markerelement.h"
#include <QTransform>

class MarkerPath
{
public:
    MarkerPath(){}

    // 重载赋值运算符
    MarkerPath& operator=(const MarkerPath &other)
    {
        if (this != &other) {
            mElements = other.mElements;
        }
        return *this;
    }

    // 重载相等性比较运算符
    bool operator==(const MarkerPath &other) const
    {
        return mElements == other.mElements;
    }

    MarkerElement first() const
    {
        return mElements.first();
    }

    MarkerElement last() const
    {
        return mElements.last();
    }

    void append(MarkerElement ele)
    {
        mElements.append(ele);
    }

    void insert(int i, MarkerElement ele)
    {
        mElements.insert(i, ele);
    }

    void moveTo(QPointF p)
    {
        MarkerElement element(p, JumpTo);
        mElements.append(element);
    }

    void moveTo(float x, float y)
    {
        moveTo(QPointF(x, y));
    }

    void lineTo(QPointF p)
    {
        MarkerElement element(p, MarkTo);
        mElements.append(element);
    }

    void lineTo(float x, float y)
    {
        lineTo(QPointF(x, y));
    }

    void arcTo(QPointF p, qreal angle)
    {
        MarkerElement element(p, angle);
        mElements.append(element);
    }

    void arcTo(float x, float y, qreal angle)
    {
        arcTo(QPointF(x, y), angle);
    }

    void laserOnMove(QPointF p, uint ms)
    {
        MarkerElement element(p, JumpLaserOn);
        element.setTime(ms);
        mElements.append(element);
    }

    void powerRampTo(QPointF p, qreal powerPercent,
                     MarkerElementType type = PowerRamp)
    {
        MarkerElement element(p, type);
        element.setPowerPercent(powerPercent);
        mElements.append(element);
    }

    /**
     * @brief length 获取总长度,这里如果是Arc_To则需要做特殊处理
     * @return
     */
    qreal length() const
    {
        qreal totalLength = 0;
        MarkerElement lastPoint;
        for(int i = 0; i < this->size(); i++){
            MarkerElement p = at(i);
            if(p.type() == JumpTo){
                lastPoint = p;
            }else{
                QLineF line(lastPoint, p);
                qreal lineLength = line.length();
                totalLength += lineLength;
                lastPoint = p;
            }
        }
        return totalLength;
    }

    QPainterPath toPainterPath() const
    {
        QPainterPath path;
        for(int i = 0; i < this->size(); i++){
            MarkerElement p = at(i);
            if(p.type() == JumpTo){
                path.moveTo(p);
            }else{
                path.lineTo(p);
            }
        }
        return path;
    }

    qreal percentAtLength(qreal t) const
    {
        QPainterPath path = this->toPainterPath();
        return path.percentAtLength(t);
    }

    QPointF pointAtPercent(qreal t) const
    {
        QPainterPath path = this->toPainterPath();
        return path.pointAtPercent(t);
    }

    qreal   angleAtPercent(qreal t) const;
    qreal   slopeAtPercent(qreal t) const;

    bool isEmpty() const
    {
        return mElements.size() == 0;
    }

    int size() const
    {
        return mElements.size();
    }

    void clear()
    {
        mElements.clear();
    }

    MarkerElement at(int index) const
    {
        Q_ASSERT(index >= 0 && index < mElements.size());
        return mElements.at(index);
    }

    MarkerElement& operator[](int index)
    {
        Q_ASSERT(index >= 0 && index < mElements.size());
        return mElements[index];
    }

    void addTransform(QTransform ma)
    {
        mTransformList.append(ma);
    }

    QTransform transformAt(int p)
    {
        return mTransformList.at(p);
    }

    int transformCount()
    {
        return mTransformList.size();
    }

    void clearTransform()
    {
        mTransformList.clear();
    }

    double width()
    {
        return mWidth;
    }

    void setWidth(double width)
    {
        mWidth = width;
    }

    double height()
    {
        return mHeight;
    }

    void setHeight(double height)
    {
        mHeight = height;
    }

private:
    QList<MarkerElement> mElements;
    QList<QTransform> mTransformList;
    double mWidth;
    double mHeight;
};
Q_DECLARE_METATYPE(MarkerPath)
#endif // MARKERPATH_H
